//
// Created on 6/1/25.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".

#include "geometry.h"
#include "glm/fwd.hpp"

Geometry::Geometry() {}

Geometry::~Geometry() {}
void Geometry::SetBBox(glm::vec3 min, glm::vec3 max) { m_bbox = {min, max}; }

void Geometry::SetVertex(std::shared_ptr<VertexProp> vertex) { m_Vertex = vertex; }
std::shared_ptr<VertexProp> Geometry::GetVertex() { return m_Vertex; }

void *Geometry::GetVertexPoint(Property property) {
    auto propertyTypeDef = GetVertex()->GetProperty(property);
    if (!propertyTypeDef)
        return nullptr;
    switch (property) {
    case Property::Vertex: {
        auto floatprop = std::dynamic_pointer_cast<PropertyType<float>>(propertyTypeDef);
        if (floatprop)
            return (void *)floatprop->m_Data.data();
        auto vec3prop = std::dynamic_pointer_cast<PropertyType<glm::vec3>>(propertyTypeDef);
        if (vec3prop)
            return (void *)vec3prop->m_Data.data();
        break;
    }
    case Property::Indices: {
        return nullptr;
        break;
    }
    case Property::Color: {
        return nullptr;
        break;
    }
    case Property::UV: {
        return nullptr;
        break;
    }
    case Property::Normal: {
        auto prop = std::dynamic_pointer_cast<PropertyType<float>>(propertyTypeDef);
        return (void *)prop->m_Data.data();
        break;
    }
    case Property::Other:{
        auto vec3prop = std::dynamic_pointer_cast<PropertyType<glm::vec3>>(propertyTypeDef);
        if (vec3prop)
            return (void *)vec3prop->m_Data.data();
        break;
    }
    default:
        return nullptr;
        break;
    }
}
void Geometry::SetPrimitiveType(PrimitiveType type) {
    m_Type = type;
}
PrimitiveType Geometry::GetPrimitiveType() {
    return m_Type;
}
int Geometry::GetVertexSize(Property property) {
    if(!GetVertex())
        return 0;
    auto propertyTypeDef = GetVertex()->GetProperty(property);
    if (!propertyTypeDef)
        return 0;
    switch (property) {
    case Property::Vertex: {
        auto floatprop = std::dynamic_pointer_cast<PropertyType<float>>(propertyTypeDef);
        if (floatprop)
            return floatprop->size();
        auto vec3prop = std::dynamic_pointer_cast<PropertyType<glm::vec3>>(propertyTypeDef);
        if (vec3prop)
            return vec3prop->size();
        break;
    }
    case Property::Indices: {
        return 0;
        break;
    }
    case Property::Color: {
        return 0;
        break;
    }
    case Property::UV: {
        return 0;
        break;
    }
    case Property::Normal: {
        auto prop = std::dynamic_pointer_cast<PropertyType<float>>(propertyTypeDef);
        return prop->size();
        break;
    }
    default:
        return 0;
    }
}
